package com.yuanfeng.payment.common;

import com.yuanfeng.commoms.config.YFConfig;
import com.yuanfeng.commoms.constant.CommonStatusEnum;
import com.yuanfeng.commoms.constant.CommonType;
import com.yuanfeng.commoms.dto.base.MemberMessageListIntegralDTO;
import com.yuanfeng.commoms.dto.order.WapGoodsSaleSumDTO;
import com.yuanfeng.commoms.exception.BizCodeEnume;
import com.yuanfeng.commoms.util.*;
import com.yuanfeng.commoms.vo.user.UserInfoVO;
import com.yuanfeng.payment.dto.AssetTmpInfoDTO;
import com.yuanfeng.payment.entity.PayUserBaseEntity;
import com.yuanfeng.payment.entity.PayUserResourceEntity;
import com.yuanfeng.payment.feign.*;
import com.yuanfeng.payment.mapper.PayAssetDetailsMapper;
import com.yuanfeng.payment.mapper.PayConsumeRecordMapper;
import com.yuanfeng.payment.mapper.PayUserBaseMapper;
import com.yuanfeng.payment.mapper.PayUserResourceMapper;
import com.yuanfeng.payment.service.PayUserResourceService;
import com.yuanfeng.payment.service.impl.ALiPayServiceImpl;
import com.yuanfeng.payment.vo.CallBackVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Stranger
 * @date 2023/4/27 10:41
 */
@Component
public class PayCommonUtils {

    @Resource
    private PayUserBaseMapper payUserBaseMapper;

    @Autowired
    private UsermsServiceClient usermsServiceClient;

    @Autowired
    private PayUserResourceService payUserResourceService;

    @Autowired
    private ALiPayServiceImpl aLiPayServiceImpl;

    @Resource
    private PayUserResourceMapper payUserResourceMapper;

    @Autowired
    private OrderServiceClient orderServiceClient;

    @Autowired
    private ActivityServiceClient activityServiceClient;

    @Resource
    private PayConsumeRecordMapper payConsumeRecordMapper;

    @Resource
    private PayAssetDetailsMapper payAssetDetailsMapper;

    @Autowired
    private BusinessServiceClient businessServiceClient;

    @Autowired
    private GoodServiceClient goodServiceClient;

    final Logger log = LoggerFactory.getLogger(PayCommonUtils.class);

    /**
     * 验证支付密码
     *
     * @param passwd
     * @param userInfo
     * @return
     */
    public ResponseResult getPwdExist(String passwd, UserInfoVO userInfo) {
        Integer isExist = 0;
        PayUserBaseEntity entity = payUserBaseMapper.selectById(userInfo.getUserId());
        // 验证支付密码
        String pwdExist = entity.getUserPayPasswd();
        if ("".equals(pwdExist)) {
            //未设置密码，请前往密码设置！
            return ResponseResult.fail(BizCodeEnume.PASSWORD_NOT_SET);
        } else if (passwd == null || "".equals(passwd) || !PasswordUtils.BCryptPasswordMatches(passwd,pwdExist)) {
            if (null!=userInfo.getIsEmployee()&&userInfo.getIsEmployee() == 1) {
                //密码错误，可联系企业管理员修改。
                return ResponseResult.fail(BizCodeEnume.PASSWORD_ERROR_ONE);
            } else {
                //密码错误，可以选择密码重置！
                return ResponseResult.fail(BizCodeEnume.PASSWORD_ERROR_TWO);
            }
        } else {
            isExist = 1;
            return ResponseResult.success(isExist);
        }
    }


    /**
     * 用户积分相关操作
     *
     * @param integralGoods
     * @param userId
     * @param amountAotalIntegral
     * @param orderId
     * @return
     */
    public ResponseResult getUserIntegral(Integer integralGoods, String userId, Integer amountAotalIntegral, String orderId) {
        if (null != integralGoods && integralGoods == 0) {
            //获取用户积分
            Integer userIntegral = usermsServiceClient.getMemberIntegralByUserId(userId);
            if (null != userIntegral && amountAotalIntegral <= userIntegral) {
                //扣除积分
                //修改会员积分和会员等级
                MemberMessageListIntegralDTO updateMemberMessageListIntegral = new MemberMessageListIntegralDTO();
                ArrayList<String> list = new ArrayList<>();
                list.add(userId);
                updateMemberMessageListIntegral.setUserIdList(list);
                updateMemberMessageListIntegral.setIntegral(amountAotalIntegral);
                //1是增加积分 0 是扣除积分
                updateMemberMessageListIntegral.setType(0);
                usermsServiceClient.updateMemberIntegral(updateMemberMessageListIntegral);
                //添加积分修改记录
                Map<String, Object> pointParam = new HashMap<>();
                pointParam.put("PointsLogType", CommonType.pointsLogType.CONSUME.getCode());
                pointParam.put("ClassId", CommonType.pointType.POINTS_EXCHANGE_VOUCHER.getCode());
                pointParam.put("PointsLogTime", LocalDateTime.now());
                pointParam.put("PointsLogDesc", CommonType.pointType.POINTS_EXCHANGE_GOODS.getDesc());
                pointParam.put("PointsLogFlag", "reg");
                pointParam.put("UserId", userId);
                pointParam.put("PointsLogPoints", amountAotalIntegral);
                pointParam.put("PointsLogOperate", CommonType.pointType.POINTS_EXCHANGE_GOODS.getDesc());
                if (null != orderId) {
                    pointParam.put("orderId", orderId);
                }
                usermsServiceClient.insertPointLogByMap(pointParam);
                return ResponseResult.success();
            } else {
                //账户积分不足
                return ResponseResult.fail(BizCodeEnume.PAY_INTEGRAL_ERROR);
            }
        }
        return ResponseResult.success();
    }

    /**
     * 支付
     *
     * @param updateMoney
     * @param token
     * @param userId
     * @param orderId
     * @param type
     * @param virtualGoods
     * @param orderIsShopTake
     * @param amountActuallyPaids
     * @param amountAotalIntegral
     * @param orderIdIsNum
     * @param callBackParaList
     * @param integralGoods
     * @param assetDetailMap
     * @param dataList
     * @return
     */
    public ResponseResult getPay(boolean updateMoney, String token, String userId, String orderId, String type,
                                 Integer virtualGoods, Integer orderIsShopTake, BigDecimal amountActuallyPaids,
                                 Integer amountAotalIntegral, Map<String, String> orderIdIsNum, List<CallBackVO> callBackParaList,
                                 Integer integralGoods, Map<Object, Object> assetDetailMap,  List<AssetTmpInfoDTO> dataList) {
        if (updateMoney) {
            PayUserResourceEntity payUserResourceEntity = payUserResourceService.getById(userId);
            //删除支付成功后积分订单的所需积分
            RedisUtil.remove(YFConfig.YF_USERINTEGRALYPAID + "--" + token + "--" + userId);
            RedisUtil.set(YFConfig.DETERMINEWHETHERTOPAY + "-" + orderId + "-" + userId + "-" + type,
                    orderId, 86400);
            // 查询账户购物卡余额
            BigDecimal afterUserGiftCardMoney = new BigDecimal(0);
            if ("1".equals(type)) {
                afterUserGiftCardMoney = payUserResourceEntity.getUserMoney();
            } else if ("2".equals(type)) {
                afterUserGiftCardMoney = payUserResourceEntity.getUserRechargeCard();
            }

            //判断是否是虚拟订单
            Map<String, Integer> judgeOrderMap = aLiPayServiceImpl.virtualWxExchangeCode(orderIdIsNum);
            virtualGoods = judgeOrderMap.get("virtualGoods");
            //存放值
            orderIsShopTake = judgeOrderMap.get("orderIsShopTake");
            Map<Object, Object> statusMap = new HashMap<Object, Object>();
            // 是纯数字订单号，存放纯数字订单
            statusMap.put("afterUserMoney", afterUserGiftCardMoney);
            statusMap.put("orderId", orderId);
            statusMap.put("token", token);
            statusMap.put("type", type);
            statusMap.put("paymentAmount", amountActuallyPaids);
            statusMap.put("amountAotalIntegral", amountAotalIntegral);
            //虚拟订单 0 是 1 否
            if (null != virtualGoods && 0 == virtualGoods) {
                statusMap.put("virtualGoods", virtualGoods);
            }
            //门店订单 0 是 1 否
            if (null != orderIsShopTake && 1 == orderIsShopTake) {
                statusMap.put("orderIsShopTake", orderIsShopTake);
            }

            // 更改销量
            List<WapGoodsSaleSumDTO> wapGood = payUserResourceMapper.queryGoodsByOrderId(orderId);
            goodServiceClient.updateGoodsSalenum(wapGood);
            // 更改订单状态
            changeStatus(statusMap);

            if ("1".equals(type) || "2".equals(type) || "12".equals(type)) {
                if (null != integralGoods && integralGoods == 0) {
                    if (amountActuallyPaids.compareTo(new BigDecimal(0)) > 0) {
                        assetDetailMap.put("assetDirection", "积分订单");
                        assetDetailMap.put("payType", Integer.valueOf(type));
                        assetDetailMap.put("userId", userId);
                        assetDetailMap.put("detailType", 6);
                        assetDetailMap.put("assetType", 2);
                        assetDetailMap.put("assetAmount", amountActuallyPaids);
                        assetDetailMap.put("orderId", dataList.get(0).getOrderId());
                        payAssetDetailsMapper.insertDetail(assetDetailMap);
                    }
                } else {

                    for (AssetTmpInfoDTO assetInfoEntity : dataList) {
                        assetDetailMap.put("assetDirection", assetInfoEntity.getShopName());
                        assetDetailMap.put("payType",Integer.valueOf(type));
                        assetDetailMap.put("userId", userId);
                        assetDetailMap.put("detailType", 6);
                        assetDetailMap.put("assetType", 2);
                        assetDetailMap.put("assetAmount", assetInfoEntity.getOrderPaymentAmount());
                        assetDetailMap.put("orderId", assetInfoEntity.getOrderId());
                        payAssetDetailsMapper.insertDetail(assetDetailMap);
                    }
                }
            }
            //支付成功
            return ResponseResult.success(BizCodeEnume.PAYMENT_SUCCESSFUL.getMsg());
        } else {
            //支付失败
            return ResponseResult.fail(BizCodeEnume.PAYMENT_FAILED);
        }
    }

    /**
     * 更改状态
     *
     * @param map
     */
    public void changeStatus(Map<Object, Object> map) {
        String orderId = (String) map.get("orderId");
        String type =  map.get("type").toString();
        Integer virtualGoods = (Integer) map.get("virtualGoods");
        Integer orderIsShopTake = (Integer) map.get("orderIsShopTake");
        Integer amountAotalIntegral = (Integer) map.get("amountAotalIntegral");
        // 支付时间
        String paymentTime = DateUtils.getNowDateToString();
        BigDecimal money = (BigDecimal) map.get("afterUserMoney");
        // 存放金额
        if (null == money) {
            money = new BigDecimal(0);
        }
        // 获取user信息
        UserInfoVO ui = ParseTokenUtils.getUserInfoByToken(map.get("token").toString());
        String userId = ui.getUserId();
        String userName = ui.getUserName();
        String buyerUserId = payUserResourceMapper.queryBuyerUserIdByOrderBase(orderId);
        try {
            // 发送feign,提交下单通知
            Map<String, Object> messageMap = new HashMap<>();
            messageMap.put("userId", userId);
            messageMap.put("userName", userName);
            // 支付号
            messageMap.put("orderId", orderId);
            messageMap.put("paymentTime", paymentTime);
            // 发送下单通知
            boolean isUpdateOrderToInform = orderServiceClient.orderToInform(messageMap).getCode() == CommonStatusEnum.SUCCESS.getCode();
            if (isUpdateOrderToInform) {
                log.info("-----OrderToInformUpdateSuccess-----");
            } else {
                log.info("-----OrderToInformUpdateFail-----");
            }

            // 更新trade&record状态
            log.info("StartUpdateTrade&RecordStatusTheFirstTime:" + DateUtils.getNowDate());
            boolean isUpdateRecordSuccess = false;
            boolean isUpdateRecordBySellerSuccess = false;
            Map<String, Object> mapRecord = new HashMap<>();
            mapRecord.put("orderId", orderId);
            mapRecord.put("money", money);
            mapRecord.put("userId", userId);
            mapRecord.put("paymentTime", paymentTime);
            mapRecord.put("amountAotalIntegral", amountAotalIntegral);
            if (PayToolUtil.isInteger(orderId)) {
                // 纯数字订单号
                // 用户，付款方
                isUpdateRecordSuccess = payConsumeRecordMapper.updateRecordByInt(mapRecord);
                // 商家，收款方
                isUpdateRecordBySellerSuccess = payConsumeRecordMapper.updateRecordBySellerInt(orderId, paymentTime);
                //获取非数字订单
                String recordPayorder = payUserResourceMapper.queryAssetInfo(orderId, null).get(0).getPaymentNumber();
                //修改拼团的支付状态
                Map<String, Object> pinTuanMap = new HashMap<>();
                pinTuanMap.put("orderId", recordPayorder);
                activityServiceClient.updatePinTuanPayStart(pinTuanMap);
            } else {
                // 非纯数字订单号
                // 用户，付款方
                isUpdateRecordSuccess = payConsumeRecordMapper.updateRecord(mapRecord);
                // 商家，收款方
                isUpdateRecordBySellerSuccess = payConsumeRecordMapper.updateRecordBySeller(orderId, paymentTime);
                //修改拼团状态
                //修改拼团的支付状态
                Map<String, Object> pinTuanMap = new HashMap<>();
                pinTuanMap.put("orderId", orderId);
                activityServiceClient.updatePinTuanPayStart(pinTuanMap);
            }
            if (isUpdateRecordSuccess && isUpdateRecordBySellerSuccess) {
                log.info("-----UpdateTrade&RecordStatusSuccess-----");
                // 发送feign请求，更改payment状态
                Map<String, Object> paymentMap = new HashMap<>();
                // 支付方式
                Integer paymentId = 1;
                // 支付方式名称
                String paymentName = "在线支付";
                if ("12".equals(type)) {
                    paymentId = 2;
                    paymentName = "线下支付";
                } else if ("1".equals(type) && !buyerUserId.equals(ui.getUserId())) {
                    paymentId = 14;
                    paymentName = "余额支付";
                } else if ("2".equals(type) && !buyerUserId.equals(ui.getUserId())) {
                    paymentId = 15;
                    paymentName = "购物卡支付";
                }
                // 分辨余额,购物卡,蜂币
                paymentMap.put("type", type);
                paymentMap.put("payOrderId", orderId);
                paymentMap.put("paymentId", paymentId);
                paymentMap.put("paymentName", paymentName);
                paymentMap.put("paymentTime", paymentTime);
                paymentMap.put("virtualGoods", virtualGoods);
                paymentMap.put("orderIsShopTake", orderIsShopTake);
                orderServiceClient.UpdateOrderBaseByPayment(paymentMap);
            }
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        } finally {
            Map<String, Object> paymentMap = new HashMap<>();
            // 支付方式
            Integer paymentId = 1;
            // 支付方式名称
            String paymentName = "在线支付";
            if ("12".equals(type)) {
                paymentId = 2;
                paymentName = "线下支付";
            } else if ("1".equals(type) && !buyerUserId.equals(ui.getUserId())) {
                paymentId = 14;
                paymentName = "余额支付";
            } else if ("2".equals(type) && !buyerUserId.equals(ui.getUserId())) {
                paymentId = 15;
                paymentName = "购物卡支付";
            }
            // 分辨余额与购物卡
            paymentMap.put("type", type);
            paymentMap.put("payOrderId", orderId);
            paymentMap.put("paymentId", paymentId);
            paymentMap.put("paymentName", paymentName);
            paymentMap.put("paymentTime", paymentTime);
            paymentMap.put("virtualGoods", virtualGoods);
            paymentMap.put("orderIsShopTake", orderIsShopTake);
            orderServiceClient.UpdateOrderBaseByPayment(paymentMap);


        }
    }

    public ResponseResult getDeteails(String orderId, String paymentNumber) {
        //新资产中心-余额够买普通商品
        List<AssetTmpInfoDTO> dataList = null;
        // 判断纯数字订单
        if (PayToolUtil.isInteger(orderId)) {
            dataList = payUserResourceMapper.queryAssetInfo(orderId, null);
        } else {
            dataList = payUserResourceMapper.queryAssetInfo(null, paymentNumber);
        }
        if (!dataList.isEmpty()) {
//            if (!DateUtils.getDateSpecific(new Date(), dataList.get(0).getOrderEndTime())) {
//                //该订单已超时，不能支付！
//                return ResponseResult.fail(BizCodeEnume.ORDER_HAS_TIMED_OUT_CANNOT_BE_PAID);
//            }
            return ResponseResult.success(dataList);
        } else {
            //未找到该订单！
            return ResponseResult.fail(BizCodeEnume.ORDER_IS_NULL);
        }
    }

    /**
     * 质保金充值
     * @return
     */
    public ResponseResult getetentionPay(Map<Object,Object> assetDetailMap,Map<Object, Object> map){

        payAssetDetailsMapper.insertDetail(assetDetailMap);

        //插入记录信息
        ResponseResult recharge = businessServiceClient.recharge(map);
        if (recharge.getCode() != 1){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();// 回滚
        }
        return recharge;
    }
}
